package com.attilax.orm;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import com.attilax.dataService.DataService;
import com.attilax.dataService.DataServiceV2;
import com.attilax.dataService.folderAsRowDataService;
import com.attilax.db.DbServiceV3Q68;
import com.attilax.io.filex;
import com.attilax.ioc.IocUtilV2;
import com.attilax.ioc.IocXq214;
import com.attilax.json.AtiJson;
import com.attilax.lang.Global;
import com.attilax.lang.Trigger;
import com.attilax.net.requestImp;
import com.attilax.sql.DbMetaService;
import com.attilax.sql.Dsl2sqlService;
import com.attilax.sql.DupliRecord;
import com.attilax.sql.SqlSecuryAnalyzer;
import com.attilax.sql.SqlService;
import com.attilax.token.TokenServiceV2;
import com.attilax.urldsl.DslUtil;
import com.attilax.user.NotLoginEx;
import com.attilax.web.ReqX;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.inject.Inject;

public class AtiOrmV2   {
	
//	@Inject
//	public 	SqlService sqlSrv;
	@Inject
	public Dsl2sqlService d2sSrv;
	
	public static void main(String[] args) {
		System.setProperty("prj", "game");
		System.setProperty("cfgfile", "cfg_game.properties");
		System.setProperty("ioccfg", "aaaCfg.Ioc4game");
		
 
		
		
 //		System.out.println(IocUtilV2.getBean(AtiOrm.class));
		AtiOrmV2 orm = IocUtilV2.getBean(AtiOrmV2.class);
 		List li = (List) orm.query("select * from agent");
 		System.out.println(li);
	}
	
	

	private String table;
	public String update="update";
	private String op;
	public Map m=Maps.newLinkedHashMap();

	
	/**
	 * com.attilax.orm.AtiOrm
	 */
public AtiOrmV2( ) {
	//this.m=m;

}

	public AtiOrmV2(Map m) {
		this.m=m;
	
	}

	public AtiOrmV2 setTable(String tb) {
		this.table=tb;
		this.m.put("$table", tb);
		return this;
	}

	public void setOp(String opString) {
		this.op=opString;
		this.m.put("$op", opString);
	}
	  @Inject
	protected
	 DbServiceV3Q68 sqlSrv;
	private String tabletype;
	public Object exe(Map m) {
		processTable(m);
		processOp(m);
	//	super.exe(m);
		String sql = d2sSrv.dsl2sql(m);
		System.out.println("dsl2sql:sqlis:"+sql);
		if (StringUtils.isEmpty(sql))
			throw new RuntimeException(
					" cant convert sql str rzt is null or empty:"+d2sSrv);
		if(sql.trim().toLowerCase().startsWith("update") || sql.trim().toLowerCase().startsWith("insert"))
			return   sqlSrv.execSql_retInt(sql);
		else
			 return   sqlSrv.executeQuery(sql);
		
	}

	public AtiOrmV2 tabletype(String tabletype) {
		this.tabletype=tabletype;
		return this;
	}
	public boolean existRzt;
	public Map querySingleRow;
	public List<Map> queryRows=Lists.newLinkedList();
	public AtiOrmV2 exist(String s) {
	    List<Map>  li=sqlSrv.executeQuery(s); 
	    if(li.size()>=0)
	    querySingleRow=li.get(0);
	    existRzt=(li.size()>=1);
	    return this;
		
	}
	
	
	public AtiOrmV2 query(String sql) {
	sql=	processPreVar4sql(sql);
	    List<Map>  li=sqlSrv.executeQuery(sql); 
	//    if(li.size()>=0)
	    this.queryRows=li;
	  //  existRzt=(li.size()>=1);
     return this;
		
	}
	
	@SuppressWarnings("all")
	public List queryAsRzt(String sql) {
	sql=	processPreVar4sql(sql);
	    List<Map>  li=sqlSrv.executeQuery(sql); 
 
	  
	 
     return li;
		
	}

	/**
	 * with uniq check
	attilax    2016年4月21日  下午9:31:19
	 * @param s
	 * @return
	 */
	public AtiOrmV2 querySingleRow(String s) {
		   List<Map>  li=sqlSrv.executeQuery(s); 
		     if(li.size()>0)
		    	 this.querySingleRow=li.get(0);
		     if(li.size()>1)
		    	 throw new DupliRecord(" sql:"+s);
		return this;
	}
	
	public AtiOrmV2 querySingleRow_NoUniqCheck(String s) {
		   List<Map>  li=sqlSrv.executeQuery(s); 
		     if(li.size()>0)
		    	 this.querySingleRow=li.get(0);
		 //    if(li.size()>1)
		    //	 throw new DupliRecord(" sql:"+s);
		return this;
	}


	public AtiOrmV2 exist(String col, String val) {
		  String sql = "select * from "+this.table+" where "+col+"='"+val+"'";
		  System.out.println(sql);
		List<Map>  li=sqlSrv.executeQuery(sql); 
		    if(li.size()>0)
		    querySingleRow=li.get(0);
		    existRzt=(li.size()>=1);
		    return this;
	}
	
	public AtiOrmV2 existUniq(String col, String val) {
		  String sql = "select * from "+this.table+" where "+col+"='"+val+"'";
		  System.out.println(sql);
		List<Map>  li=sqlSrv.executeQuery(sql); 
		  if(li.size()>1)
		    	 throw new DupliRecord(" sql:"+sql);
		    if(li.size()>0)
		    	querySingleRow=li.get(0);
		    existRzt=(li.size()>=1);
		    return this;
	}
	
	public static int notExistCount=0;
	private static void copyFile(String pathx)   {
		try {
			System.out.println(" proce is ing:"+pathx);
			String path="z:\\"+pathx;
			String path_noDsk=path.substring(3);
			String new_path="f:\\0localImgX\\"+path_noDsk;
			filex.createAllPath(new_path);
			File file = new File(path);
			if(new File(new_path).exists())
				return;
			if(!file.exists())
			{
				notExistCount++;
				System.out.println(" not exist count:"+notExistCount);
				System.out.println(" file not exist:"+path);
				return;
			}
			if(new File(new_path).exists())
				return;
			System.out.println("  coopy "+path +">>>"+ new_path);
			FileUtils.copyFile(file, new File(new_path));
		} catch (Exception e) {
			System.out.println(pathx+e.getMessage());
		}
		
	}
	public Trigger trigr;
	
//	  @Inject
//	protected
//	 SqlService sqlSrv;
	//  @Inject
	//  DBX dbx;
	  
	 public static void main2(String[] args) {
		System.out.println("--");
		
		requestImp ri=new requestImp();
		ri.setParam("$table", "hitv");
		ri.setParam("$where", " genre like '%动画%'");
		Global.req.set(ri);
		DataServiceV2 ds=IocXq214.getBean(DataServiceV2.class);
		Object rows = ds. exe();
		System.out.println( AtiJson.toJson( rows));
	}
//$storeEngiee=folderAsRow  
	public Object exe() {

		 
		HttpServletRequest req = Global.req.get();
		
		String table=getTable(req);
		if(table.trim().startsWith("update"))
		{
			String sql=table.trim();
		   new SqlSecuryAnalyzer().parse4upOrDel(sql);
			return sqlSrv.executeUpdate(req.getParameter("$tb"));
		}
		String tableType =getTableType(req);
		if(tableTypeIsSql(tableType))   //def is table type
			
			return sqlSrv.executeQuery(table);
		tksvr2.setModule(req.getParameter("$utype") + "Mod");
		if(req.getParameter("$utype")==null)
			tksvr2.setModule("userMod");
		//trigger pos:before
		if (req.getParameter("$trigger") != null  && req.getParameter("$triggerPos")==null ) // p319
		{
			String tiggerName = req.getParameter("$trigger");
			Object trigger = IocXq214.getBean(tiggerName);
			this.trigr = (Trigger) trigger;
		}
		
		//q46
		Global.dbName.set("$defdb");
		if(req.getParameter("$db")!=null)
		{
			Global.dbName.set(req.getParameter("$db"));
		}

		@SuppressWarnings("rawtypes")
		Map m = ReqX.toMap(req);
		processTable(m);
		processOp(m);
		
		processPreVar(req, m);
		// fld fun
		DslUtil.appFldFun(m);
		if (trigr != null)
			trigr.exec(m);
		if(m.get("$storeEngiee")!=null)
			if(m.get("$storeEngiee").equals("folderAsRow"))
					return new folderAsRowDataService().exe(m);
				
		metaSvr.createNewCol(m);	   
		Object rows = dsl2sqlV2q326(m);
		if(m.get("$trigger")!=null && m.get("$triggerPos").equals("after") )
		{
		   Trigger o=  	IocXq214.getBean(m.get("$trigger").toString());
		   rows=  o.exec(rows);
		}
		return rows;

	}
 //	@Inject
 	DbMetaService metaSvr;
	private void processPreVar(HttpServletRequest req, Map m) {
		Set<String> st = m.keySet();
		for (String k : st) {
			if (m.get(k).equals("$cur_uid")) {
				String getuid = tksvr2.getuid(req);
				if (StringUtils.isEmpty(getuid))
					throw new NotLoginEx("NotLoginEx");
				m.put(k, getuid);
			}
			
			if (m.get(k).equals("$uid")) {
				String getuid = tksvr2.getuid(req);
				if (StringUtils.isEmpty(getuid))
					throw new NotLoginEx("NotLoginEx");
				m.put(k, getuid);
			}
			if (m.get(k).toString().equals("$uuid")) {
				m.put(k, filex.getUUidName());
			}
		}
		// fld fun
		DslUtil.appFldFun(m);
		if (trigr != null)
			trigr.exec(m);
//		if(m.get("$storeEngiee")!=null)
//			if(m.get("$storeEngiee").equals("folderAsRow"))
//					return new folderAsRowDataService().exe(m);
				
				
//		Object rows = dsl2sqlV2q326(m);
//		if(m.get("$trigger")!=null && m.get("$triggerPos").equals("after") )
//		{
//		   Trigger o=  	IocXq214.getBean(m.get("$trigger").toString());
//		   rows=  o.exec(rows);
//		}
//		return rows;
		 

	}

	/**
	attilax    2016年4月19日  下午5:40:44
	 * @param table
	 */
	private void checkLogin(String sql) {
		if(sql.contains("$uid$"))
		if(StringUtils.isEmpty(tksvr2.getuid()))
			throw new NotLoginEx("");
		
	}
	/**
attilax    2016年4月19日  下午5:40:20
 * @param req
 */
private void checkLogin(HttpServletRequest req) {
	// TODO Auto-generated method stub
	
}


	protected void processOp(Map m) {
	String op = getOp(m);
	if (op.equals("i"))
		m.put("$op", "insert");
	if(op==null)
		m.put("$op","select");
	if(op.equals("q"))
		m.put("$op","select");
	
}
protected void processTable(Map m) {
	if (m.get("$table") == null)
		m.put("$table", m.get("$tb"));
}

	private boolean tableTypeIsSql(String tableType) {
	if(	tableType!=null && tableType.equals("sq"))
		return true;
	if(	tableType!=null && tableType.equals("sql"))
		return true;
		return false;
	}
	private String getOp(Map m) {
		return	(String) m.get("$op");
	//./return null;
}
	private String getTableType(HttpServletRequest req) {
		if( !StringUtils.isEmpty( req.getParameter("$tbtype")))
			return req.getParameter("$tbtype");
		if( !StringUtils.isEmpty( req.getParameter("$tabletype")))
			return req.getParameter("$tabletype");
	return null;
}
	/**
	attilax    2016年4月12日  下午10:26:51
	 * @param req
	 * @return
	 */
	private String getTable(HttpServletRequest req) {
		if(req.getParameter("$tb")!=null)
			return req.getParameter("$tb");
		if(req.getParameter("$table")!=null)
			return req.getParameter("$table");
		 
		return null;
	}
	
//	public Object exe(String sql) {
//		if(sql.trim().toLowerCase().startsWith("update") || sql.trim().toLowerCase().startsWith("insert"))
//		{
//			 
//			return  execSql_retInt(sql);
//		}
//		return executeQuery(sql);
//		// TODO Auto-generated method stub
//		
//	}
	//com.attilax.sql.Dsl2sqlService@4dc8d72b
	private Object dsl2sqlV2q326(Map m) {
		String sql = d2sSrv.dsl2sql(m);
		sql=processPreVar4sql(sql);
		System.out.println(sql);
		if (StringUtils.isEmpty(sql))
			throw new RuntimeException(
					" cant convert sql str rzt is null or empty:"+d2sSrv);
		if(sql.trim().toLowerCase().startsWith("update") || sql.trim().toLowerCase().startsWith("insert"))
			return   sqlSrv.execSql_retInt(sql);
		else
		return sqlSrv.executeQuery(sql);
	}
	@Inject
	TokenServiceV2 tksvr2;
	/**
	attilax    2016年4月21日  下午10:05:05
	 * @param sql
	 * @return
	 */
	private String processPreVar4sql(String sql) {
	
		
		if(sql.contains("$uid$"))
		{
			HttpServletRequest req=Global.req.get();
			tksvr2.setUtype(req.getParameter("$utype"));
			if(StringUtils.isEmpty(tksvr2.getuid()))
				throw new NotLoginEx("NotLoginEx");
			sql = sql.replace("$uid$", tksvr2.getuid());
		}
      if(sql.contains("$uid"))
			sql = sql.replace("$uid", tksvr2.getuid());
		return sql;
	}
	
//	private String processPreVar4sql(String sql) {
//		sql = sql.replace("$uid$", tkSrv.getuid());
//		return sql;
//	}
	
	

}
